*! 1.2.0 NJC 16 May 2004 
* 1.1.0 NJC 13 May 2003 
* 1.0.0 NJC 19 January 2003 
program extremes, sortpreserve byable(recall)  
	version 8 
	syntax varlist [if] [in] [ , n(numlist max=1 int >=1) MISSing /// 
		iqr(numlist max=1 >=0) IQR2 FREQuencies HIgh LOw noHeader * ]

	if "`iqr'`iqr2'" != "" & "`frequencies'" != "" { 
		di as err "may not combine iqr and frequencies options"
		exit 198 
	}	
	
	tokenize `varlist' 
	local varname "`1'" 
	confirm numeric variable `varname' 
	mac shift 
	local varlist "`*'" 
	if "`frequencies'" != "" & "`varlist'" != "" { 
		di as err "may not specify other variables" ///
		" with frequencies option"
		exit 198 
	}	

	marksample touse, novarlist 
	markout `touse' `varname' 
	if _by() & "`missing'" == "" { 
		markout `touse' `_byvars', strok 
	} 	

	qui count if `touse' 
	if r(N) == 0 error 2000 
	local use = r(N) 
	local notuse = _N - r(N)

        if "`high'" == "" & "`low'" == "" { 
		// default: want both 
		local high 1
		local low  1 
	} 	
	else { 
		local high = "`high'" == "high" 
		local low  = "`low'" == "low" 
	}
	
	qui if "`frequencies'" == "" {
		tempvar obsno sobsno
		gen long `obsno' = _n 
		gen str `sobsno' = string(_n) + "." 
		char `sobsno'[varname] "obs:" 
	} 	

	if "`iqr2'" != "" { 
		if "`iqr'" == "" local iqr = 1.5 
		// -iqr()- specified as well takes precedence 
	} 
	
	qui if "`iqr'" != "" { 
		tempvar dev 
		tempname IQR 
		su `varname' if `touse', detail 
		if r(p75) == r(p25) { 
			di as err "iqr is 0" 
			exit 459 
		} 	
		scalar `IQR' = r(p75) - r(p25) 
		gen `dev' = (`varname' - r(p75)) / `IQR' /// 
			if `varname' >= r(p75) & `touse' 
		replace `dev' = (`varname' - r(p25)) / `IQR' /// 
			if `varname' <= r(p25) & `touse'
		format `dev' %4.3f 
		char `dev'[varname] "iqr:" 
		count if `dev' >= `iqr' & `dev' < . 
		local nhigh = r(N)
		count if `dev' <= -`iqr'
		local nlow = r(N)
		sort `touse' `varname' `obsno' 
		
		local blank 0 
		if `low' & `nlow' { 
			noi list `sobsno' `dev' `varname' `varlist'  ///
				if `dev' <= -`iqr', noobs subvarname ///
				`header' `options' 
			if "`header'" == "" local noheader "noheader"  
			local blank 1
		} 	
	        if `high' & `nhigh' { 
			if `blank' di
			noi list `sobsno' `dev' `varname' `varlist' ///
				if `dev' >= `iqr' & `dev' < .       ///
			        , `header' `noheader' noobs subvarname `options'
		} 
	} 	
	else if "`frequencies'" != "" {
		if "`n'" == "" local n = 5 
				
		tempvar freq isfreq 
		qui bysort `touse' `varname' : ///
			gen long `freq' = _N * (_n == 1) * `touse'
		char `freq'[varname] "freq:" 
		by `touse' `varname' : gen byte `isfreq' = `freq' > 0 
			
		qui count if `isfreq'  
		local nfreq = r(N) 
		if `nfreq' <= `n' { 
		        // irrespective of options, show all 
			local high 0 
			local low  1 
		} 	
		
		local l1 = _N - `nfreq' + 1 
		local l2 = min(`l1' + `n' - 1, _N) 
		local h1 = max(_N -`n' + 1, `l2' + 1) 
		
	        sort `touse' `isfreq' `varname'  
		local blank 0 
		if `low' { 
			list `freq' `varname' `varlist' in `l1'/`l2' ///
				, noobs subvarname `header' `options'
			if "`header'" == "" local noheader "noheader"  
			local blank 1
		} 	
		if `high' { 
			if `blank' di
			list `freq' `varname' `varlist' in `h1'/l ///
				, `header' `noheader' noobs subvarname `options' 
		} 
	} 
	else { 
		if "`n'" == "" local n = 5 
		
		if `use' <= `n' { 
		        // irrespective of options, show all 
			local high 0 
			local low  1 
		} 	
		
		local l1 = `notuse' + 1 
		local l2 = min(`l1' + `n' - 1, _N) 
		local h1 = max(_N -`n' + 1, `l2' + 1) 
		
		sort `touse' `varname' `obsno' 
		local blank 0 
		if `low' { 
			list `sobsno' `varname' `varlist' in `l1'/`l2' ///
				, noobs subvarname `header' `options'
			if "`header'" == "" local noheader "noheader"  
			local blank 1
		} 	
		if `high' { 
			if `blank' di
			list `sobsno' `varname' `varlist' in `h1'/l ///
				, `header' `noheader' noobs subvarname `options' 
		} 
		
		local goon 1
		local blank 1 
		if `low' & `varname'[`l2'] == `varname'[`l2'+1] {
			di 
			qui count if `varname' == `varname'[`l2'] & `touse'
			local show : di `: format `varname'' `varname'[`l2'] 
			local show = trim("`show'") 
			di as txt "note: " as res `r(N)' ///
				as txt " values of " as res `show' 
			local goon = `varname'[`l2'] != `varname'[`h1']  
			local blank 0 
		} 	
		
		if `goon' & `high' & (`varname'[`h1'] == `varname'[`h1'-1]) { 
			if `blank' di 
			qui count if `varname' == `varname'[`h1'] & `touse'
			local show : di `: format `varname'' `varname'[`h1'] 
			local show = trim("`show'") 
			di as txt "note: " as res `r(N)' /// 
				as txt " values of "  as res `show' 
		} 
	}	
end
